/* Copyright (C) 2005-2013, Unigine Corp. All rights reserved.
 *
 * File:    fragment_base_sample.h
 * Desc:    Terrain base sample shader
 * Version: 1.16
 * Author:  Alexander Zapryagaev <frustum@unigine.com>
 *
 * This file is part of the Unigine engine (http://unigine.com/).
 *
 * Your use and or redistribution of this software in source and / or
 * binary form, with or without modification, is subject to: (i) your
 * ongoing acceptance of and compliance with the terms and conditions of
 * the Unigine License Agreement; and (ii) your inclusion of this notice
 * in any version of this software that you use or redistribute.
 * A copy of the Unigine License Agreement is available by contacting
 * Unigine Corp. at http://unigine.com/
 */

/******************************************************************************\
*
* OpenGL
*
\******************************************************************************/

#ifdef OPENGL
	
	#ifdef PATCH
		
		half4 diffuse = texture(s_texture_0,lerp(s_texcoord_0.xy,s_texcoord_0.zw,s_terrain_texcoord.x));
		
		#ifdef DETAIL_0_OVERLAY || DETAIL_0_OVERLAP || DETAIL_1_OVERLAY || DETAIL_1_OVERLAP || DETAIL_2_OVERLAY || DETAIL_2_OVERLAP || DETAIL_3_OVERLAY || DETAIL_3_OVERLAP
			
			half3 normal = half3(0.0f);
			half3 basis_normal = texture2DNormal(s_texture_1,lerp(s_texcoord_0.xy,s_texcoord_0.zw,s_terrain_texcoord.y));
			half3 basis_binormal = normalize(cross(half3(-1.0f,0.0f,0.0f),basis_normal));
			half3 basis_tangent = normalize(cross(basis_binormal,basis_normal));
			
			half4 mask = texture(s_texture_2,lerp(s_texcoord_0.xy,s_texcoord_0.zw,s_terrain_texcoord.z)) * s_texcoord_6.x;
			half4 diffuse_scale = s_terrain_diffuse_scale * mask;
			half4 normal_scale = s_terrain_normal_scale * mask;
			
			#ifdef PATCH_TRIPLANAR
				
				half3 weight = basis_normal * basis_normal;
				weight /= dot(weight,half3(1.0f));
				
				half4 diffuse_scale_xy = diffuse_scale * weight.z;
				half4 diffuse_scale_xz = diffuse_scale * weight.y;
				half4 diffuse_scale_yz = diffuse_scale * weight.x;
				half4 normal_scale_xy = normal_scale * weight.z;
				half4 normal_scale_xz = normal_scale * weight.y;
				half4 normal_scale_yz = normal_scale * weight.x;
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,s_texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = texture(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = texture(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = texture(s_texture_ ## DIFFUSE,texcoord_yz); \
						half3 detail_normal_xy = texture2DNormal(s_texture_ ## NORMAL,texcoord_xy); \
						half3 detail_normal_xz = texture2DNormal(s_texture_ ## NORMAL,texcoord_xz); \
						half3 detail_normal_yz = texture2DNormal(s_texture_ ## NORMAL,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
						normal.xy += detail_normal_xy.xy * normal_scale_xy. ## SWIZZLE; \
						normal.xy += detail_normal_xz.xy * normal_scale_xz. ## SWIZZLE; \
						normal.xy += detail_normal_yz.xy * normal_scale_yz. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,s_texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = texture(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = texture(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = texture(s_texture_ ## DIFFUSE,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
					}
				#endif
				
			#else
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = texture(s_texture_ ## DIFFUSE,texcoord); \
						half3 detail_normal = texture2DNormal(s_texture_ ## NORMAL,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
						normal.xy += detail_normal.xy * normal_scale. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = texture(s_texture_ ## DIFFUSE,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
					}
				#endif
				
			#endif
			
			#ifdef QUALITY_MEDIUM
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = texture(s_texture_ ## DIFFUSE,texcoord); \
					half3 detail_normal = texture2DNormal(s_texture_ ## NORMAL,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
					normal.xy = lerp(normal.xy,detail_normal.xy,detail_alpha * s_terrain_normal_scale. ## SWIZZLE); \
				}
			#else
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = s_texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = texture(s_texture_ ## DIFFUSE,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
				}
			#endif
			
			#ifdef DETAIL_0_OVERLAY
				DETAIL_OVERLAY(3,4,0,x);
			#elif DETAIL_0_OVERLAP
				DETAIL_OVERLAP(3,4,0,x);
			#endif
			#ifdef DETAIL_1_OVERLAY
				DETAIL_OVERLAY(5,6,1,y);
			#elif DETAIL_1_OVERLAP
				DETAIL_OVERLAP(5,6,1,y);
			#endif
			#ifdef DETAIL_2_OVERLAY
				DETAIL_OVERLAY(7,8,2,z);
			#elif DETAIL_2_OVERLAP
				DETAIL_OVERLAP(7,8,2,z);
			#endif
			#ifdef DETAIL_3_OVERLAY
				DETAIL_OVERLAY(9,10,3,w);
			#elif DETAIL_3_OVERLAP
				DETAIL_OVERLAP(9,10,3,w);
			#endif
			
			#undef DETAIL_OVERLAY
			#undef DETAIL_OVERLAP
			
			normal = normalize(basis_normal + basis_tangent * normal.x + basis_binormal * normal.y);
			
		#else
			
			half3 normal = texture2DNormal(s_texture_1,lerp(s_texcoord_0.xy,s_texcoord_0.zw,s_terrain_texcoord.y));
			
		#endif
		
	#else
		
		half4 diffuse = texture(s_texture_0,s_texcoord_0.zw);
		half3 normal = texture2DNormal(s_texture_1,s_texcoord_0.zw);
		
	#endif
	
	#ifdef USE_SRGB
		diffuse.xyz *= diffuse.xyz;
	#endif
	
	half3 specular = diffuse.xyz * diffuse.w;
	
/******************************************************************************\
*
* Direct3D11
*
\******************************************************************************/

#elif DIRECT3D11
	
	#ifdef PATCH
		
		half4 diffuse = s_texture_0.Sample(s_sampler_0,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.x));
		
		#ifdef DETAIL_0_OVERLAY || DETAIL_0_OVERLAP || DETAIL_1_OVERLAY || DETAIL_1_OVERLAP || DETAIL_2_OVERLAY || DETAIL_2_OVERLAP || DETAIL_3_OVERLAY || DETAIL_3_OVERLAP
			
			half3 normal = 0.0f;
			half3 basis_normal = texture2DNormal(s_texture_1,s_sampler_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			half3 basis_binormal = normalize(cross(half3(-1.0f,0.0f,0.0f),basis_normal));
			half3 basis_tangent = normalize(cross(basis_binormal,basis_normal));
			
			half4 mask = s_texture_2.Sample(s_sampler_2,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.z)) * IN.texcoord_6.x;
			half4 diffuse_scale = s_terrain_diffuse_scale * mask;
			half4 normal_scale = s_terrain_normal_scale * mask;
			
			#ifdef PATCH_TRIPLANAR
				
				half3 weight = basis_normal * basis_normal;
				weight /= dot(weight,1.0f);
				
				half4 diffuse_scale_xy = diffuse_scale * weight.z;
				half4 diffuse_scale_xz = diffuse_scale * weight.y;
				half4 diffuse_scale_yz = diffuse_scale * weight.x;
				half4 normal_scale_xy = normal_scale * weight.z;
				half4 normal_scale_xz = normal_scale * weight.y;
				half4 normal_scale_yz = normal_scale * weight.x;
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_yz); \
						half3 detail_normal_xy = texture2DNormal(s_texture_ ## NORMAL,s_sampler_ ## NORMAL,texcoord_xy); \
						half3 detail_normal_xz = texture2DNormal(s_texture_ ## NORMAL,s_sampler_ ## NORMAL,texcoord_xz); \
						half3 detail_normal_yz = texture2DNormal(s_texture_ ## NORMAL,s_sampler_ ## NORMAL,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
						normal.xy += detail_normal_xy.xy * normal_scale_xy. ## SWIZZLE; \
						normal.xy += detail_normal_xz.xy * normal_scale_xz. ## SWIZZLE; \
						normal.xy += detail_normal_yz.xy * normal_scale_yz. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
					}
				#endif
				
			#else
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord); \
						half3 detail_normal = texture2DNormal(s_texture_ ## NORMAL,s_sampler_ ## NORMAL,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
						normal.xy += detail_normal.xy * normal_scale. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
					}
				#endif
				
			#endif
			
			#ifdef QUALITY_MEDIUM
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord); \
					half3 detail_normal = texture2DNormal(s_texture_ ## NORMAL,s_sampler_ ## NORMAL,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
					normal.xy = lerp(normal.xy,detail_normal.xy,detail_alpha * s_terrain_normal_scale. ## SWIZZLE); \
				}
			#else
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = s_texture_ ## DIFFUSE .Sample(s_sampler_ ## DIFFUSE,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
				}
			#endif
			
			#ifdef DETAIL_0_OVERLAY
				DETAIL_OVERLAY(3,4,0,x);
			#elif DETAIL_0_OVERLAP
				DETAIL_OVERLAP(3,4,0,x);
			#endif
			#ifdef DETAIL_1_OVERLAY
				DETAIL_OVERLAY(5,6,1,y);
			#elif DETAIL_1_OVERLAP
				DETAIL_OVERLAP(5,6,1,y);
			#endif
			#ifdef DETAIL_2_OVERLAY
				DETAIL_OVERLAY(7,8,2,z);
			#elif DETAIL_2_OVERLAP
				DETAIL_OVERLAP(7,8,2,z);
			#endif
			#ifdef DETAIL_3_OVERLAY
				DETAIL_OVERLAY(9,10,3,w);
			#elif DETAIL_3_OVERLAP
				DETAIL_OVERLAP(9,10,3,w);
			#endif
			
			#undef DETAIL_OVERLAY
			#undef DETAIL_OVERLAP
			
			normal = normalize(basis_normal + basis_tangent * normal.x + basis_binormal * normal.y);
			
		#else
			
			half3 normal = texture2DNormal(s_texture_1,s_sampler_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			
		#endif
		
	#else
		
		half4 diffuse = s_texture_0.Sample(s_sampler_0,IN.texcoord_0.zw);
		half3 normal = texture2DNormal(s_texture_1,s_sampler_1,IN.texcoord_0.zw);
		
	#endif
	
	#ifdef USE_SRGB
		diffuse.xyz *= diffuse.xyz;
	#endif
	
	half3 specular = diffuse.xyz * diffuse.w;
	
/******************************************************************************\
*
* Direct3D9
*
\******************************************************************************/

#elif DIRECT3D9
	
	#ifdef PATCH
		
		half4 diffuse = tex2D(s_texture_0,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.x));
		
		#ifdef DETAIL_0_OVERLAY || DETAIL_0_OVERLAP || DETAIL_1_OVERLAY || DETAIL_1_OVERLAP || DETAIL_2_OVERLAY || DETAIL_2_OVERLAP || DETAIL_3_OVERLAY || DETAIL_3_OVERLAP
			
			half3 normal = 0.0f;
			half3 basis_normal = tex2DNormal(s_texture_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			half3 basis_binormal = normalize(cross(half3(-1.0f,0.0f,0.0f),basis_normal));
			half3 basis_tangent = normalize(cross(basis_binormal,basis_normal));
			
			half4 mask = tex2D(s_texture_2,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.z)) * IN.texcoord_6.x;
			half4 diffuse_scale = s_terrain_diffuse_scale * mask;
			half4 normal_scale = s_terrain_normal_scale * mask;
			
			#ifdef PATCH_TRIPLANAR
				
				half3 weight = basis_normal * basis_normal;
				weight /= dot(weight,1.0f);
				
				half4 diffuse_scale_xy = diffuse_scale * weight.z;
				half4 diffuse_scale_xz = diffuse_scale * weight.y;
				half4 diffuse_scale_yz = diffuse_scale * weight.x;
				half4 normal_scale_xy = normal_scale * weight.z;
				half4 normal_scale_xz = normal_scale * weight.y;
				half4 normal_scale_yz = normal_scale * weight.x;
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = tex2D(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = tex2D(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = tex2D(s_texture_ ## DIFFUSE,texcoord_yz); \
						half3 detail_normal_xy = tex2DNormal(s_texture_ ## NORMAL,texcoord_xy); \
						half3 detail_normal_xz = tex2DNormal(s_texture_ ## NORMAL,texcoord_xz); \
						half3 detail_normal_yz = tex2DNormal(s_texture_ ## NORMAL,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
						normal.xy += detail_normal_xy.xy * normal_scale_xy. ## SWIZZLE; \
						normal.xy += detail_normal_xz.xy * normal_scale_xz. ## SWIZZLE; \
						normal.xy += detail_normal_yz.xy * normal_scale_yz. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_6.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = tex2D(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = tex2D(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = tex2D(s_texture_ ## DIFFUSE,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
					}
				#endif
				
			#else
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = tex2D(s_texture_ ## DIFFUSE,texcoord); \
						half3 detail_normal = tex2DNormal(s_texture_ ## NORMAL,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
						normal.xy += detail_normal.xy * normal_scale. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = tex2D(s_texture_ ## DIFFUSE,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
					}
				#endif
				
			#endif
			
			#ifdef QUALITY_MEDIUM
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = tex2D(s_texture_ ## DIFFUSE,texcoord); \
					half3 detail_normal = tex2DNormal(s_texture_ ## NORMAL,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
					normal.xy = lerp(normal.xy,detail_normal.xy,detail_alpha * s_terrain_normal_scale. ## SWIZZLE); \
				}
			#else
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = tex2D(s_texture_ ## DIFFUSE,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
				}
			#endif
			
			#ifdef DETAIL_0_OVERLAY
				DETAIL_OVERLAY(3,4,0,x);
			#elif DETAIL_0_OVERLAP
				DETAIL_OVERLAP(3,4,0,x);
			#endif
			#ifdef DETAIL_1_OVERLAY
				DETAIL_OVERLAY(5,6,1,y);
			#elif DETAIL_1_OVERLAP
				DETAIL_OVERLAP(5,6,1,y);
			#endif
			#ifdef DETAIL_2_OVERLAY
				DETAIL_OVERLAY(7,8,2,z);
			#elif DETAIL_2_OVERLAP
				DETAIL_OVERLAP(7,8,2,z);
			#endif
			#ifdef DETAIL_3_OVERLAY
				DETAIL_OVERLAY(9,10,3,w);
			#elif DETAIL_3_OVERLAP
				DETAIL_OVERLAP(9,10,3,w);
			#endif
			
			#undef DETAIL_OVERLAY
			#undef DETAIL_OVERLAP
			
			normal = normalize(basis_normal + basis_tangent * normal.x + basis_binormal * normal.y);
			
		#else
			
			half3 normal = tex2DNormal(s_texture_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			
		#endif
		
	#else
		
		half4 diffuse = tex2D(s_texture_0,IN.texcoord_0.zw);
		half3 normal = tex2DNormal(s_texture_1,IN.texcoord_0.zw);
		
	#endif
	
	#ifdef USE_SRGB
		diffuse.xyz *= diffuse.xyz;
	#endif
	
	half3 specular = diffuse.xyz * diffuse.w;
	
/******************************************************************************\
*
* PlayStation3
*
\******************************************************************************/

#elif PLAYSTATION3
	
	#ifdef PATCH
		
		half4 diffuse = h4tex2D(s_texture_0,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.x));
		
		#ifdef DETAIL_0_OVERLAY || DETAIL_0_OVERLAP || DETAIL_1_OVERLAY || DETAIL_1_OVERLAP || DETAIL_2_OVERLAY || DETAIL_2_OVERLAP || DETAIL_3_OVERLAY || DETAIL_3_OVERLAP
			
			half3 normal = 0.0f;
			half3 basis_normal = tex2DNormal(s_texture_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			half3 basis_binormal = normalize(cross(half3(-1.0f,0.0f,0.0f),basis_normal));
			half3 basis_tangent = normalize(cross(basis_binormal,basis_normal));
			
			half4 mask = h4tex2D(s_texture_2,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.z)) * IN.texcoord_8.x;
			half4 diffuse_scale = s_terrain_diffuse_scale * mask;
			half4 normal_scale = s_terrain_normal_scale * mask;
			
			#ifdef PATCH_TRIPLANAR
				
				half3 weight = basis_normal * basis_normal;
				weight /= dot(weight,1.0f);
				
				half4 diffuse_scale_xy = diffuse_scale * weight.z;
				half4 diffuse_scale_xz = diffuse_scale * weight.y;
				half4 diffuse_scale_yz = diffuse_scale * weight.x;
				half4 normal_scale_xy = normal_scale * weight.z;
				half4 normal_scale_xz = normal_scale * weight.y;
				half4 normal_scale_yz = normal_scale * weight.x;
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_8.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = h4tex2D(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = h4tex2D(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = h4tex2D(s_texture_ ## DIFFUSE,texcoord_yz); \
						half3 detail_normal_xy = tex2DNormal(s_texture_ ## NORMAL,texcoord_xy); \
						half3 detail_normal_xz = tex2DNormal(s_texture_ ## NORMAL,texcoord_xz); \
						half3 detail_normal_yz = tex2DNormal(s_texture_ ## NORMAL,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
						normal.xy += detail_normal_xy.xy * normal_scale_xy. ## SWIZZLE; \
						normal.xy += detail_normal_xz.xy * normal_scale_xz. ## SWIZZLE; \
						normal.xy += detail_normal_yz.xy * normal_scale_yz. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord_xy = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						float2 texcoord_xz = float2(texcoord_xy.x,IN.texcoord_8.y * s_terrain_transform_ ## NUM.x); \
						float2 texcoord_yz = float2(texcoord_xy.y,texcoord_xz.y); \
						half4 detail_diffuse_xy = h4tex2D(s_texture_ ## DIFFUSE,texcoord_xy); \
						half4 detail_diffuse_xz = h4tex2D(s_texture_ ## DIFFUSE,texcoord_xz); \
						half4 detail_diffuse_yz = h4tex2D(s_texture_ ## DIFFUSE,texcoord_yz); \
						diffuse = saturate(diffuse + (detail_diffuse_xy * 2.0f - 1.0f) * diffuse_scale_xy. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_xz * 2.0f - 1.0f) * diffuse_scale_xz. ## SWIZZLE); \
						diffuse = saturate(diffuse + (detail_diffuse_yz * 2.0f - 1.0f) * diffuse_scale_yz. ## SWIZZLE); \
					}
				#endif
				
			#else
				
				#ifdef QUALITY_MEDIUM
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = h4tex2D(s_texture_ ## DIFFUSE,texcoord); \
						half3 detail_normal = tex2DNormal(s_texture_ ## NORMAL,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
						normal.xy += detail_normal.xy * normal_scale. ## SWIZZLE; \
					}
				#else
					#define DETAIL_OVERLAY(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
						float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
						half4 detail_diffuse = h4tex2D(s_texture_ ## DIFFUSE,texcoord); \
						diffuse = saturate(diffuse + (detail_diffuse * 2.0f - 1.0f) * diffuse_scale. ## SWIZZLE); \
					}
				#endif
				
			#endif
			
			#ifdef QUALITY_MEDIUM
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = h4tex2D(s_texture_ ## DIFFUSE,texcoord); \
					half3 detail_normal = tex2DNormal(s_texture_ ## NORMAL,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
					normal.xy = lerp(normal.xy,detail_normal.xy,detail_alpha * s_terrain_normal_scale. ## SWIZZLE); \
				}
			#else
				#define DETAIL_OVERLAP(DIFFUSE,NORMAL,NUM,SWIZZLE) { \
					float2 texcoord = IN.texcoord_0.xy * s_terrain_transform_ ## NUM.xy + s_terrain_transform_ ## NUM.zw; \
					half4 detail_diffuse = h4tex2D(s_texture_ ## DIFFUSE,texcoord); \
					half detail_alpha = saturate((detail_diffuse.w * mask. ## SWIZZLE - s_terrain_overlap_value. ## SWIZZLE) * s_terrain_overlap_ithreshold. ## SWIZZLE); \
					diffuse.xyz = lerp(diffuse.xyz,detail_diffuse.xyz,detail_alpha * s_terrain_diffuse_scale. ## SWIZZLE); \
				}
			#endif
			
			#ifdef DETAIL_0_OVERLAY
				DETAIL_OVERLAY(3,4,0,x);
			#elif DETAIL_0_OVERLAP
				DETAIL_OVERLAP(3,4,0,x);
			#endif
			#ifdef DETAIL_1_OVERLAY
				DETAIL_OVERLAY(5,6,1,y);
			#elif DETAIL_1_OVERLAP
				DETAIL_OVERLAP(5,6,1,y);
			#endif
			#ifdef DETAIL_2_OVERLAY
				DETAIL_OVERLAY(7,8,2,z);
			#elif DETAIL_2_OVERLAP
				DETAIL_OVERLAP(7,8,2,z);
			#endif
			#ifdef DETAIL_3_OVERLAY
				DETAIL_OVERLAY(9,10,3,w);
			#elif DETAIL_3_OVERLAP
				DETAIL_OVERLAP(9,10,3,w);
			#endif
			
			#undef DETAIL_OVERLAY
			#undef DETAIL_OVERLAP
			
			normal = normalize(basis_normal + basis_tangent * normal.x + basis_binormal * normal.y);
			
		#else
			
			half3 normal = tex2DNormal(s_texture_1,lerp(IN.texcoord_0.xy,IN.texcoord_0.zw,s_terrain_texcoord.y));
			
		#endif
		
	#else
		
		half4 diffuse = h4tex2D(s_texture_0,IN.texcoord_0.zw);
		half3 normal = tex2DNormal(s_texture_1,IN.texcoord_0.zw);
		
	#endif
	
	#ifdef USE_SRGB
		diffuse.xyz *= diffuse.xyz;
	#endif
	
	half3 specular = diffuse.xyz * diffuse.w;
	
#endif
